package com.haifeng.mywriteaidldemo.MyAIDL;

import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.io.FileDescriptor;

/***
 * 因为继承了binder所以具备跨进程传输的能力
 * 他必须实现我们接口定义的方法
 */
public abstract class Stub extends Binder implements MyInterface {

    private static final String DESCRIPTOR = "com.haifeng.mywriteaidldemo.MyInterface";

    public Stub() {
        //向binderservice注册该binder，
        this.attachInterface(this, DESCRIPTOR);
    }

    /***
     *  将binder对象转化为接口 并判断是否返回代理对象
     * @param binder
     * @return
     */
    public static MyInterface anInterface(IBinder binder) {
        if (binder == null) {
            return null;
        }
        IInterface ii = binder.queryLocalInterface(DESCRIPTOR);//查询本地binder 如果存在则说明 client与service在同一个进程直接本地调用
        if (ii != null && ii instanceof MyInterface) {
            return (MyInterface) ii;
        }
        //否则 返回代理对象
        return new Proxy(binder);
    }

    /**
     * 代理对象调用方法 并将客户端数据进行处理并跨进程传输到服务端
     * @param code
     * @param data
     * @param reply
     * @param flags
     * @return
     * @throws RemoteException
     */
    @Override
    protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
        String descriptor = DESCRIPTOR;
        switch (code) {
            case INTERFACE_TRANSACTION: {
                reply.writeString(descriptor);
                return true;
            }
            case TRANCACTION_ADDNAME: {
                data.enforceInterface(descriptor);
                String _data = data.readString();
                this.addname(_data);
                reply.writeNoException();
                return true;
            }
            case TRANCACTION_GETNAME: {
                data.enforceInterface(descriptor);
                String _position = data.readString();
                String _name = this.getname(_position);
                reply.writeNoException();
                reply.writeString(_name);
                return true;
            }
            default: {
                return super.onTransact(code, data, reply, flags);
            }
        }

    }

    @Override
    public IBinder asBinder() {
        return this;
    }

    static final int TRANCACTION_ADDNAME = (FIRST_CALL_TRANSACTION + 0);
    static final int TRANCACTION_GETNAME = (FIRST_CALL_TRANSACTION + 1);

    public static boolean setDefaultImpl(MyInterface i) {
        if (Proxy.minterface != null) {

        }
        if (i != null) {
            Proxy.minterface = i;
            return true;
        }
        return false;
    }

    public static MyInterface getDefaultImpl(){
        return Proxy.minterface;
    }
}
